<!--
  ETF页面说明：
  本页面用于展示和管理ETF（交易型开放式指数基金）相关数据，支持添加、删除、买入、卖出ETF，
  并可根据不同策略（如上升、回撤、回归、RSI等）对ETF进行筛选和排序。
  页面集成了机会筛选（isOpportunity/isOpportunityV2），并通过下拉刷新、按钮交互等方式实现数据的动态获取和操作。
-->
<template>
  <div class="main-box">
    <van-nav-bar
      title="ETF"
      left-arrow
      @click-left="onClickLeft"
    />

    <section class="search-section">
      <van-field
        v-model="etfCode"
        placeholder="输入代码或名称"
        clearable
      />
      <van-button
        type="primary"
        class="control-btn"
        @click="onSearch"
      >
        搜索
      </van-button>
      <van-button
        type="success"
        class="control-btn"
        @click="onAdd"
      >
        添加
      </van-button>
      <van-button
        plain
        type="warning"
        class="control-btn"
        @click="onResetFilters"
      >
        重置
      </van-button>
    </section>

    <section class="filter-section">
      <div class="stepper-block">
        <span class="stepper-label">窗口</span>
        <van-stepper
          v-model="query.num"
          theme="round"
          button-size="30"
          min="1"
          max="60"
        />
      </div>
      <van-dropdown-menu class="filter-menu">
        <van-dropdown-item
          v-model="query.unit"
          :options="unitOptions"
          @change="onUnitChange"
        />
        <van-dropdown-item
          v-model="query.sortKey"
          :options="sortOptions"
          @change="onSortChange"
        />
      </van-dropdown-menu>
    </section>

    <div class="list-div">
      <van-pull-refresh
        v-model="loading"
        @refresh="refresh"
      >
        <van-empty
          v-if="showEmpty"
          description="暂无数据"
        />
        <template v-else>
          <van-swipe-cell
            v-for="item in deliveryItems"
            :key="`${item.code}-${item.rank}`"
          >
            <van-cell
              center
              :class="item.holdFlag === 0 ? 'white-cell' : 'blue-cell'"
            >
              <template #title>
                <div class="cell-title">
                  <div>
                    <span class="code">{{ item.code }}</span>
                    <span class="name">{{ item.name }}</span>
                  </div>
                  <div class="cell-tags">
                    <van-tag
                      size="mini"
                      type="primary"
                    >
                      #{{ item.rank }}
                    </van-tag>
                    <van-tag
                      size="mini"
                      plain
                      :type="item.holdFlag === 0 ? 'default' : 'success'"
                    >
                      {{ item.holdFlagText }}
                    </van-tag>
                  </div>
                </div>
              </template>
              <template #label>
                <div class="label-row">
                  <span>净值：{{ formatNumber(item.value) }}</span>
                  <span>涨跌：{{ formatNumber(item.dailyRate, 2, '%') }}</span>
                </div>
                <div class="label-row">
                  <span>区间：{{ formatNumber(item.rang) }}</span>
                  <span>位置：{{ formatNumber(item.position, 2, '%') }}</span>
                  <span>RSI：{{ formatNumber(item.rsi) }}</span>
                  <span>量比：{{ formatNumber(item.volumeRatio) }}</span>
                  <span>回撤：{{ formatNumber(item.hcf, 2, '%') }}</span>
                </div>
                <div class="label-row">
                  <span>最近涨跌：{{ formatNumber(item.lastUpDown) }}</span>
                  <span>周期：{{ item.days || '--' }} 天</span>
                </div>
                <div class="label-row date-row">
                  <span>{{ item.startDate || '--' }} - {{ item.endDate || '--' }}</span>
                </div>
              </template>
            </van-cell>
            <template #right>
              <van-button
                square
                class="right-btn"
                :type="item.holdFlag === 0 ? 'success' : 'danger'"
                @click="toggleHold(item)"
                :text="item.holdFlag === 0 ? '买入' : '卖出'"
              />
            </template>
            <template #left>
              <van-button
                square
                class="right-btn"
                type="danger"
                text="删除"
                @click="remove(item)"
              />
            </template>
          </van-swipe-cell>
        </template>
      </van-pull-refresh>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { showToast } from 'vant'
import {
  delivery as fetchDeliveryApi,
  etfAdd,
  etfRemove,
  setHoldFlag as setHoldFlagApi
} from '@/requests/etf'

const router = useRouter()

const sortDefaultDirMap = {
  position: 'asc',
  rsi: 'asc',
  updown: 'asc',
  rang: 'desc',
  hcf: 'asc'
}

const etfCode = ref('')
const loading = ref(false)
const refreshLoading = ref(false)
const rawDeliveryItems = ref([])
const deliverySummary = ref(null)
const deliveryFilters = ref({
  unitOptions: [],
  sortOptions: []
})

const query = reactive({
  unit: 'weeks',
  num: 3,
  sortKey: 'rsi',
  sortDir: 'asc',
  code: ''
})

const summary = computed(() => deliverySummary.value)
const unitOptions = computed(() => {
  const fallback = [
    { text: '年', value: 'years' },
    { text: '月', value: 'months' },
    { text: '周', value: 'weeks' },
    { text: '日', value: 'days' }
  ]
  const options = deliveryFilters.value.unitOptions || fallback
  return options.map((option) => ({
    text: option.text,
    value: option.value
  }))
})

const sortOptions = computed(() => {
  const fallback = [
    { text: '位置', value: 'position' },
    { text: 'RSI', value: 'rsi' },
    { text: '涨跌', value: 'updown' },
    { text: '区间', value: 'rang' },
    { text: '回撤', value: 'hcf' }
  ]
  const options = deliveryFilters.value.sortOptions || fallback
  // 过滤掉 value 为 'value' 和 'regression' 的选项（最新净值、回归斜率）
  return options
    .filter((option) => option.value !== 'value' && option.value !== 'regression')
    .map((option) => ({
      text: option.text,
      value: option.value
    }))
})

const unitLabel = computed(() => {
  const match = unitOptions.value.find((option) => option.value === query.unit)
  return match?.text || '周'
})

const sortItems = (items, sortKey, sortDir) => {
  if (!items || items.length === 0) {
    return []
  }

  // 创建副本以避免修改原始数据
  const sortedItems = [...items]

  // 根据 sortKey 获取对应的字段值
  const getSortValue = (item) => {
    switch (sortKey) {
      case 'position':
        return item.position
      case 'rsi':
        return item.rsi
      case 'updown':
        return item.lastUpDown
      case 'rang':
        return item.rang
      case 'hcf':
        return item.hcf
      default:
        return item.position
    }
  }

  // 排序函数
  sortedItems.sort((a, b) => {
    const aVal = getSortValue(a)
    const bVal = getSortValue(b)

    // null 值排在最后
    if (aVal === null || aVal === undefined) {
      return 1
    }
    if (bVal === null || bVal === undefined) {
      return -1
    }

    // 数值比较
    const aNum = Number(aVal)
    const bNum = Number(bVal)

    if (Number.isNaN(aNum) || Number.isNaN(bNum)) {
      return 0
    }

    const diff = aNum - bNum
    return sortDir === 'desc' ? -diff : diff
  })

  // 更新 rank 字段（创建新对象以避免修改原始数据）
  return sortedItems.map((item, index) => ({
    ...item,
    rank: index + 1
  }))
}

const deliveryItems = computed(() => {
  return sortItems(rawDeliveryItems.value, query.sortKey, query.sortDir)
})

const showEmpty = computed(() => !loading.value && deliveryItems.value.length === 0)

const formatNumber = (value, precision = 2, suffix = '') => {
  if (value === null || value === undefined) {
    return '--'
  }
  const num = Number(value)
  if (Number.isNaN(num)) {
    return '--'
  }
  return `${num.toFixed(precision)}${suffix}`
}

const buildPayload = () => {
  const payload = { ...query }
  if (!payload.code) {
    delete payload.code
  }
  return payload
}

const fetchDelivery = async () => {
  loading.value = true
  try {
    const res = await fetchDeliveryApi(buildPayload())
    if (res.code === 200) {
      const data = res.data || {}
      rawDeliveryItems.value = data.items || []
      deliverySummary.value = data.summary || null
      deliveryFilters.value = data.filters || deliveryFilters.value
    } else {
      showToast(res.message || '获取失败')
    }
  } catch (error) {
    showToast(error.message || '获取失败')
  } finally {
    loading.value = false
    refreshLoading.value = false
  }
}

const onClickLeft = () => {
  router.back()
}

const onSearch = () => {
  query.code = etfCode.value.trim()
  fetchDelivery()
}

const onAdd = async () => {
  if (!etfCode.value) {
    onSearch()
    return
  }
  showToast('添加中')
  try {
    const res = await etfAdd(etfCode.value)
    if (res.code === 200) {
      etfCode.value = ''
      fetchDelivery()
    } else {
      showToast(res.message)
    }
  } catch (error) {
    showToast(error.message)
  }
}

const toggleHold = async (item) => {
  const nextFlag = item.holdFlag === 0 ? 3 : 0
  try {
    const res = await setHoldFlagApi(item.code, nextFlag)
    if (res.code === 200) {
      fetchDelivery()
    } else {
      showToast(res.message)
    }
  } catch (error) {
    showToast(error.message)
  }
}

const remove = async (item) => {
  try {
    const res = await etfRemove(item.code)
    if (res.code === 200) {
      fetchDelivery()
    } else {
      showToast(res.message)
    }
  } catch (error) {
    showToast(error.message)
  }
}

const onSortChange = (value) => {
  applySortKey(value)
}

const applySortKey = (value) => {
  query.sortKey = value
  query.sortDir = sortDefaultDirMap[value] || 'asc'
}

const onUnitChange = () => {
  query.num = query.unit === 'days' ? 7 : 3
}

const onResetFilters = () => {
  Object.assign(query, {
    unit: 'weeks',
    num: 3,
    sortKey: 'rsi',
    sortDir: 'asc',
    code: ''
  })
  etfCode.value = ''
  fetchDelivery()
}

const refresh = async () => {
  refreshLoading.value = true
  await fetchDelivery()
}

const loadDefaultSort = () => {
  applySortKey('rsi')
}

// 监听非排序参数变化，需要重新请求接口
watch(
  () => [query.unit, query.num, query.code],
  () => {
    fetchDelivery()
  }
)

// 如果当前排序键不在可用选项中（如 'value' 已被删除），自动切换到默认排序
watch(
  sortOptions,
  (options) => {
    const availableValues = options.map((opt) => opt.value)
    if (!availableValues.includes(query.sortKey)) {
      applySortKey('rsi')
    }
  },
  { immediate: true }
)

// 排序参数变化时，deliveryItems 计算属性会自动更新，无需请求接口

onMounted(() => {
  fetchDelivery()
})
</script>

<style scoped lang="scss">
.main-box {
  height: 100vh;
  overflow: hidden;
  background-color: #f5f7fa;
  display: flex;
  flex-direction: column;
}

.search-section {
  flex-shrink: 0;
  z-index: 100;
  background-color: #f5f7fa;
  display: flex;
  gap: 8px;
  padding: 8px 12px;
  align-items: center;

  .control-btn {
    flex: 0 0 auto;
  }

  :deep(.van-field) {
    flex: 1;
  }
}

.filter-section {
  flex-shrink: 0;
  z-index: 100;
  background-color: #f5f7fa;
  padding: 6px 12px;
  display: flex;
  align-items: center;
  gap: 12px;

  .filter-menu {
    flex: 1;
  }

  .stepper-block {
    display: flex;
    align-items: center;
    gap: 4px;
    background: #fff;
    padding: 6px 10px;
    border-radius: 8px;
  }

  .stepper-label {
    font-size: 12px;
    color: #888;
  }
}

.list-div {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 0 8px 60px;

  .cell-title {
    display: flex;
    justify-content: space-between;
    align-items: center;

    .code {
      font-weight: bold;
      margin-right: 8px;
    }

    .name {
      color: #666;
    }

    .cell-tags {
      display: flex;
      gap: 6px;
    }
  }

  .label-row {
    display: flex;
    flex-wrap: wrap;
    font-size: 12px;
    color: #555;
    gap: 8px;
    margin-top: 4px;
  }

  .date-row {
    color: #888;
  }

  .right-btn {
    height: 100%;
  }

  .blue-cell {
    background-color: #e6f9ef;
  }

  .white-cell {
    background-color: #fff;
  }
}
</style>
